home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / clang / cweb31.zip / COMMON.C < prev    next >
C/C++ Source or Header  |  1993-11-08  |  22KB  |  1,240 lines

  1. /*1:*/
  2. #line 57 "common.w"
  3.  
  4. /*5:*/
  5. #line 101 "common.w"
  6.  
  7. #include <ctype.h>
  8.  
  9. /*:5*//*8:*/
  10. #line 163 "common.w"
  11.  
  12. #include <stdio.h>
  13.  
  14. /*:8*//*22:*/
  15. #line 468 "common.w"
  16.  
  17. #include <stdlib.h> 
  18.  
  19. /*:22*/
  20. #line 58 "common.w"
  21.  
  22. #define ctangle 0
  23. #define cweave 1 \
  24.  
  25. #define and_and 04
  26. #define lt_lt 020
  27. #define gt_gt 021
  28. #define plus_plus 013
  29. #define minus_minus 01
  30. #define minus_gt 031
  31. #define not_eq 032
  32. #define lt_eq 034
  33. #define gt_eq 035
  34. #define eq_eq 036
  35. #define or_or 037
  36. #define dot_dot_dot 016
  37. #define colon_colon 06
  38. #define period_ast 026
  39. #define minus_gt_ast 027 \
  40.  
  41. #define buf_size 100
  42. #define long_buf_size 500
  43. #define xisspace(c)(isspace(c)&&((unsigned char)c<0200))
  44. #define xisupper(c)(isupper(c)&&((unsigned char)c<0200)) \
  45.  
  46. #define max_include_depth 10 \
  47.  
  48. #define max_file_name_length 60
  49. #define cur_file file[include_depth]
  50. #define cur_file_name file_name[include_depth]
  51. #define cur_line line[include_depth]
  52. #define web_file file[0]
  53. #define web_file_name file_name[0] \
  54.  
  55. #define lines_dont_match (change_limit-change_buffer!=limit-buffer|| \
  56. strncmp(buffer,change_buffer,limit-buffer)) \
  57.  
  58. #define if_section_start_make_pending(b){*limit= '!'; \
  59. for(loc= buffer;xisspace(*loc);loc++); \
  60. *limit= ' '; \
  61. if(*loc=='@'&&(xisspace(*(loc+1))||*(loc+1)=='*'))change_pending= b; \
  62. } \
  63.  
  64. #define max_sections 2000 \
  65.  \
  66.  
  67. #define too_long(){include_depth--; \
  68. err_print("! Include file name too long");goto restart;} \
  69.  
  70. #define max_bytes 90000 \
  71.  
  72. #define max_names 4000 \
  73.  \
  74.  
  75. #define length(c)(c+1)->byte_start-(c)->byte_start
  76. #define print_id(c)term_write((c)->byte_start,length((c))) \
  77.  
  78. #define hash_size 353 \
  79.  
  80. #define llink link
  81. #define rlink dummy.Rlink
  82. #define root name_dir->rlink \
  83.  \
  84.  
  85. #define first_chunk(p)((p)->byte_start+2)
  86. #define prefix_length(p)(int)((unsigned char)*((p)->byte_start)*256+ \
  87. (unsigned char)*((p)->byte_start+1))
  88. #define set_prefix_length(p,m)(*((p)->byte_start)= (m)/256, \
  89. *((p)->byte_start+1)= (m)%256) \
  90.  
  91. #define less 0
  92. #define equal 1
  93. #define greater 2
  94. #define prefix 3
  95. #define extension 4 \
  96.  
  97. #define bad_extension 5 \
  98.  
  99. #define spotless 0
  100. #define harmless_message 1
  101. #define error_message 2
  102. #define fatal_message 3
  103. #define mark_harmless {if(history==spotless)history= harmless_message;}
  104. #define mark_error history= error_message \
  105.  
  106. #define confusion(s)fatal("! This can't happen: ",s) \
  107.  \
  108.  
  109. #define show_banner flags['b']
  110. #define show_progress flags['p']
  111. #define show_stats flags['s']
  112. #define show_happiness flags['h'] \
  113.  
  114. #define update_terminal fflush(stdout) \
  115.  
  116. #define new_line putchar('\n')
  117. #define putxchar putchar
  118. #define term_write(a,b)fflush(stdout),fwrite(a,sizeof(char),b,stdout)
  119. #define C_printf(c,a)fprintf(C_file,c,a)
  120. #define C_putc(c)putc(c,C_file) \
  121.  
  122.  
  123. #line 59 "common.w"
  124.  
  125. /*2:*/
  126. #line 72 "common.w"
  127.  
  128. typedef short boolean;
  129. boolean program;
  130.  
  131. /*:2*//*7:*/
  132. #line 157 "common.w"
  133.  
  134. char buffer[long_buf_size];
  135. char*buffer_end= buffer+buf_size-2;
  136. char*limit= buffer;
  137. char*loc= buffer;
  138.  
  139. /*:7*//*10:*/
  140. #line 212 "common.w"
  141.  
  142. int include_depth;
  143. FILE*file[max_include_depth];
  144. FILE*change_file;
  145. char file_name[max_include_depth][max_file_name_length];
  146.  
  147. char change_file_name[max_file_name_length];
  148. char alt_web_file_name[max_file_name_length];
  149. int line[max_include_depth];
  150. int change_line;
  151. int change_depth;
  152. boolean input_has_ended;
  153. boolean changing;
  154. boolean web_file_open= 0;
  155.  
  156. /*:10*//*20:*/
  157. #line 416 "common.w"
  158.  
  159. typedef unsigned short sixteen_bits;
  160. sixteen_bits section_count;
  161. boolean changed_section[max_sections];
  162. boolean change_pending;
  163.  
  164. boolean print_where= 0;
  165.  
  166. /*:20*//*27:*/
  167. #line 586 "common.w"
  168.  
  169. typedef struct name_info{
  170. char*byte_start;
  171. /*31:*/
  172. #line 623 "common.w"
  173.  
  174. struct name_info*link;
  175.  
  176. /*:31*//*40:*/
  177. #line 722 "common.w"
  178.  
  179. union{
  180. struct name_info*Rlink;
  181.  
  182. char Ilk;
  183. }dummy;
  184.  
  185. /*:40*//*55:*/
  186. #line 1054 "common.w"
  187.  
  188. char*equiv_or_xref;
  189.  
  190. /*:55*/
  191. #line 589 "common.w"
  192.  
  193. }name_info;
  194. typedef name_info*name_pointer;
  195. char byte_mem[max_bytes];
  196. char*byte_mem_end= byte_mem+max_bytes-1;
  197. name_info name_dir[max_names];
  198. name_pointer name_dir_end= name_dir+max_names-1;
  199.  
  200. /*:27*//*29:*/
  201. #line 609 "common.w"
  202.  
  203. name_pointer name_ptr;
  204. char*byte_ptr;
  205.  
  206. /*:29*//*32:*/
  207. #line 636 "common.w"
  208.  
  209. typedef name_pointer*hash_pointer;
  210. name_pointer hash[hash_size];
  211. hash_pointer hash_end= hash+hash_size-1;
  212. hash_pointer h;
  213.  
  214. /*:32*//*56:*/
  215. #line 1074 "common.w"
  216.  
  217. int history= spotless;
  218.  
  219. /*:56*//*67:*/
  220. #line 1212 "common.w"
  221.  
  222. int argc;
  223. char**argv;
  224. char C_file_name[max_file_name_length];
  225. char tex_file_name[max_file_name_length];
  226. char idx_file_name[max_file_name_length];
  227. char scn_file_name[max_file_name_length];
  228. boolean flags[128];
  229.  
  230. /*:67*//*77:*/
  231. #line 1366 "common.w"
  232.  
  233. FILE*C_file;
  234. FILE*tex_file;
  235. FILE*idx_file;
  236. FILE*scn_file;
  237. FILE*active_file;
  238.  
  239. /*:77*/
  240. #line 60 "common.w"
  241.  
  242. /*3:*/
  243. #line 82 "common.w"
  244. int phase;
  245.  
  246. /*:3*//*11:*/
  247. #line 238 "common.w"
  248.  
  249. char change_buffer[buf_size];
  250. char*change_limit;
  251.  
  252. /*:11*/
  253. #line 61 "common.w"
  254.  
  255. /*33:*/
  256. #line 642 "common.w"
  257.  
  258. extern int names_match();
  259.  
  260. /*:33*//*38:*/
  261. #line 695 "common.w"
  262.  
  263. void init_p();
  264.  
  265. /*:38*//*46:*/
  266. #line 844 "common.w"
  267.  
  268. extern void init_node();
  269.  
  270. /*:46*//*53:*/
  271. #line 1009 "common.w"
  272.  
  273. int section_name_cmp();
  274.  
  275. /*:53*//*57:*/
  276. #line 1084 "common.w"
  277.  
  278. void err_print();
  279.  
  280. /*:57*//*60:*/
  281. #line 1132 "common.w"
  282.  
  283. int wrap_up();
  284. extern void print_stats();
  285.  
  286. /*:60*//*63:*/
  287. #line 1165 "common.w"
  288.  
  289. void fatal(),overflow();
  290.  
  291. /*:63*//*69:*/
  292. #line 1243 "common.w"
  293.  
  294. void scan_args();
  295.  
  296. /*:69*//*81:*/
  297. #line 1407 "common.w"
  298.  
  299. extern int strlen();
  300. extern int strcmp();
  301. extern char*strcpy();
  302. extern int strncmp();
  303. extern char*strncpy();
  304.  
  305. /*:81*/
  306. #line 62 "common.w"
  307.  
  308.  
  309. /*:1*//*4:*/
  310. #line 88 "common.w"
  311.  
  312. void
  313. common_init()
  314. {
  315. /*30:*/
  316. #line 613 "common.w"
  317.  
  318. name_dir->byte_start= byte_ptr= byte_mem;
  319. name_ptr= name_dir+1;
  320. name_ptr->byte_start= byte_mem;
  321.  
  322. /*:30*//*34:*/
  323. #line 647 "common.w"
  324.  
  325. for(h= hash;h<=hash_end;*h++= NULL);
  326.  
  327. /*:34*//*41:*/
  328. #line 729 "common.w"
  329.  
  330. root= NULL;
  331.  
  332. /*:41*/
  333. #line 92 "common.w"
  334. ;
  335. /*68:*/
  336. #line 1225 "common.w"
  337.  
  338. show_banner= show_happiness= show_progress= 1;
  339.  
  340. /*:68*/
  341. #line 93 "common.w"
  342. ;
  343. /*78:*/
  344. #line 1373 "common.w"
  345.  
  346. scan_args();
  347. if(program==ctangle){
  348. if((C_file= fopen(C_file_name,"w"))==NULL)
  349. fatal("! Cannot open output file ",C_file_name);
  350.  
  351. }
  352. else{
  353. if((tex_file= fopen(tex_file_name,"w"))==NULL)
  354. fatal("! Cannot open output file ",tex_file_name);
  355. }
  356.  
  357. /*:78*/
  358. #line 94 "common.w"
  359. ;
  360. }
  361.  
  362. /*:4*//*9:*/
  363. #line 170 "common.w"
  364.  
  365. int input_ln(fp)
  366. FILE*fp;
  367. {
  368. register int c= EOF;
  369. register char*k;
  370. if(feof(fp))return(0);
  371. limit= k= buffer;
  372. while(k<=buffer_end&&(c= getc(fp))!=EOF&&c!='\n')
  373. if((*(k++)= c)!=' ')limit= k;
  374. if(k>buffer_end)
  375. if((c= getc(fp))!=EOF&&c!='\n'){
  376. ungetc(c,fp);loc= buffer;err_print("! Input line too long");
  377.  
  378. }
  379. if(c==EOF&&limit==buffer)return(0);
  380.  
  381. return(1);
  382. }
  383.  
  384. /*:9*//*12:*/
  385. #line 249 "common.w"
  386.  
  387. void
  388. prime_the_change_buffer()
  389. {
  390. change_limit= change_buffer;
  391. /*13:*/
  392. #line 263 "common.w"
  393.  
  394. while(1){
  395. change_line++;
  396. if(!input_ln(change_file))return;
  397. if(limit<buffer+2)continue;
  398. if(buffer[0]!='@')continue;
  399. if(xisupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  400. if(buffer[1]=='x')break;
  401. if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
  402. loc= buffer+2;
  403. err_print("! Missing @x in change file");
  404.  
  405. }
  406. }
  407.  
  408. /*:13*/
  409. #line 254 "common.w"
  410. ;
  411. /*14:*/
  412. #line 280 "common.w"
  413.  
  414. do{
  415. change_line++;
  416. if(!input_ln(change_file)){
  417. err_print("! Change file ended after @x");
  418.  
  419. return;
  420. }
  421. }while(limit==buffer);
  422.  
  423. /*:14*/
  424. #line 255 "common.w"
  425. ;
  426. /*15:*/
  427. #line 290 "common.w"
  428.  
  429. {
  430. change_limit= change_buffer-buffer+limit;
  431. strncpy(change_buffer,buffer,limit-buffer+1);
  432. }
  433.  
  434. /*:15*/
  435. #line 256 "common.w"
  436. ;
  437. }
  438.  
  439. /*:12*//*16:*/
  440. #line 318 "common.w"
  441.  
  442. void
  443. check_change()
  444. {
  445. int n= 0;
  446. if(lines_dont_match)return;
  447. change_pending= 0;
  448. if(!changed_section[section_count]){
  449. if_section_start_make_pending(1);
  450. if(!change_pending)changed_section[section_count]= 1;
  451. }
  452. while(1){
  453. changing= 1;print_where= 1;change_line++;
  454. if(!input_ln(change_file)){
  455. err_print("! Change file ended before @y");
  456.  
  457. change_limit= change_buffer;changing= 0;
  458. return;
  459. }
  460. if(limit>buffer+1&&buffer[0]=='@'){
  461. if(xisupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  462. /*17:*/
  463. #line 356 "common.w"
  464.  
  465. if(buffer[1]=='x'||buffer[1]=='z'){
  466. loc= buffer+2;err_print("! Where is the matching @y?");
  467.  
  468. }
  469. else if(buffer[1]=='y'){
  470. if(n>0){
  471. loc= buffer+2;
  472. printf("\n! Hmm... %d ",n);
  473. err_print("of the preceding lines failed to match");
  474.  
  475. }
  476. change_depth= include_depth;
  477. return;
  478. }
  479.  
  480. /*:17*/
  481. #line 340 "common.w"
  482. ;
  483. }
  484. /*15:*/
  485. #line 290 "common.w"
  486.  
  487. {
  488. change_limit= change_buffer-buffer+limit;
  489. strncpy(change_buffer,buffer,limit-buffer+1);
  490. }
  491.  
  492. /*:15*/
  493. #line 342 "common.w"
  494. ;
  495. changing= 0;cur_line++;
  496. while(!input_ln(cur_file)){
  497. if(include_depth==0){
  498. err_print("! CWEB file ended during a change");
  499.  
  500. input_has_ended= 1;return;
  501. }
  502. include_depth--;cur_line++;
  503. }
  504. if(lines_dont_match)n++;
  505. }
  506. }
  507.  
  508. /*:16*//*18:*/
  509. #line 376 "common.w"
  510.  
  511. void
  512. reset_input()
  513. {
  514. limit= buffer;loc= buffer+1;buffer[0]= ' ';
  515. /*19:*/
  516. #line 391 "common.w"
  517.  
  518. if((web_file= fopen(web_file_name,"r"))==NULL){
  519. strcpy(web_file_name,alt_web_file_name);
  520. if((web_file= fopen(web_file_name,"r"))==NULL)
  521. fatal("! Cannot open input file ",web_file_name);
  522. }
  523.  
  524.  
  525. web_file_open= 1;
  526. if((change_file= fopen(change_file_name,"r"))==NULL)
  527. fatal("! Cannot open change file ",change_file_name);
  528.  
  529. /*:19*/
  530. #line 381 "common.w"
  531. ;
  532. include_depth= 0;cur_line= 0;change_line= 0;
  533. change_depth= include_depth;
  534. changing= 1;prime_the_change_buffer();changing= !changing;
  535. limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= 0;
  536. }
  537.  
  538. /*:18*//*21:*/
  539. #line 424 "common.w"
  540.  
  541. int get_line()
  542. {
  543. restart:
  544. if(changing&&include_depth==change_depth)
  545. /*25:*/
  546. #line 529 "common.w"
  547. {
  548. change_line++;
  549. if(!input_ln(change_file)){
  550. err_print("! Change file ended without @z");
  551.  
  552. buffer[0]= '@';buffer[1]= 'z';limit= buffer+2;
  553. }
  554. if(limit>buffer){
  555. if(change_pending){
  556. if_section_start_make_pending(0);
  557. if(change_pending){
  558. changed_section[section_count]= 1;change_pending= 0;
  559. }
  560. }
  561. *limit= ' ';
  562. if(buffer[0]=='@'){
  563. if(xisupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  564. if(buffer[1]=='x'||buffer[1]=='y'){
  565. loc= buffer+2;
  566. err_print("! Where is the matching @z?");
  567.  
  568. }
  569. else if(buffer[1]=='z'){
  570. prime_the_change_buffer();changing= !changing;print_where= 1;
  571. }
  572. }
  573. }
  574. }
  575.  
  576. /*:25*/
  577. #line 429 "common.w"
  578. ;
  579. if(!changing||include_depth>change_depth){
  580. /*24:*/
  581. #line 512 "common.w"
  582. {
  583. cur_line++;
  584. while(!input_ln(cur_file)){
  585. print_where= 1;
  586. if(include_depth==0){input_has_ended= 1;break;}
  587. else{
  588. fclose(cur_file);include_depth--;
  589. if(changing&&include_depth==change_depth)break;
  590. cur_line++;
  591. }
  592. }
  593. if(!changing&&!input_has_ended)
  594. if(limit-buffer==change_limit-change_buffer)
  595. if(buffer[0]==change_buffer[0])
  596. if(change_limit>change_buffer)check_change();
  597. }
  598.  
  599. /*:24*/
  600. #line 431 "common.w"
  601. ;
  602. if(changing&&include_depth==change_depth)goto restart;
  603. }
  604. loc= buffer;*limit= ' ';
  605. if(*buffer=='@'&&(*(buffer+1)=='i'||*(buffer+1)=='I')){
  606. loc= buffer+2;
  607. while(loc<=limit&&(*loc==' '||*loc=='\t'||*loc=='"'))loc++;
  608. if(loc>=limit){
  609. err_print("! Include file name not given");
  610.  
  611. goto restart;
  612. }
  613. if(include_depth>=max_include_depth-1){
  614. err_print("! Too many nested includes");
  615.  
  616. goto restart;
  617. }
  618. include_depth++;
  619. /*23:*/
  620. #line 471 "common.w"
  621. {
  622. char temp_file_name[max_file_name_length];
  623. char*cur_file_name_end= cur_file_name+max_file_name_length-1;
  624. char*k= cur_file_name,*kk;
  625. int l;
  626.  
  627. while(*loc!=' '&&*loc!='\t'&&*loc!='"'&&k<=cur_file_name_end)*k++= *loc++;
  628. if(k>cur_file_name_end)too_long();
  629.  
  630. *k= '\0';
  631. if((cur_file= fopen(cur_file_name,"r"))!=NULL){
  632. cur_line= 0;print_where= 1;
  633. goto restart;
  634. }
  635. kk= getenv("CWEBINPUTS");
  636. if(kk!=NULL){
  637. if((l= strlen(kk))>max_file_name_length-2)too_long();
  638. strcpy(temp_file_name,kk);
  639. }
  640. else{
  641. #ifdef CWEBINPUTS
  642. if((l= strlen(CWEBINPUTS))>max_file_name_length-2)too_long();
  643. strcpy(temp_file_name,CWEBINPUTS);
  644. #else
  645. l= 0;
  646. #endif 
  647. }
  648. if(l>0){
  649. if(k+l+2>=cur_file_name_end)too_long();
  650.  
  651. for(;k>=cur_file_name;k--)*(k+l+1)= *k;
  652. strcpy(cur_file_name,temp_file_name);
  653. cur_file_name[l]= '/';
  654. if((cur_file= fopen(cur_file_name,"r"))!=NULL){
  655. cur_line= 0;print_where= 1;
  656. goto restart;
  657. }
  658. }
  659. include_depth--;err_print("! Cannot open include file");goto restart;
  660. }
  661.  
  662. /*:23*/
  663. #line 449 "common.w"
  664. ;
  665. }
  666. return(!input_has_ended);
  667. }
  668.  
  669. /*:21*//*26:*/
  670. #line 561 "common.w"
  671.  
  672. void
  673. check_complete(){
  674. if(change_limit!=change_buffer){
  675. strncpy(buffer,change_buffer,change_limit-change_buffer+1);
  676. limit= buffer+(int)(change_limit-change_buffer);
  677. changing= 1;change_depth= include_depth;loc= buffer;
  678. err_print("! Change file entry did not match");
  679.  
  680. }
  681. }
  682.  
  683. /*:26*//*35:*/
  684. #line 652 "common.w"
  685.  
  686. name_pointer
  687. id_lookup(first,last,t)
  688. char*first;
  689. char*last;
  690. char t;
  691. {
  692. char*i= first;
  693. int h;
  694. int l;
  695. name_pointer p;
  696. if(last==NULL)for(last= first;*last!='\0';last++);
  697. l= last-first;
  698. /*36:*/
  699. #line 675 "common.w"
  700.  
  701. h= (unsigned char)*i;
  702. while(++i<last)h= (h+h+(int)((unsigned char)*i))%hash_size;
  703.  
  704.  
  705. /*:36*/
  706. #line 665 "common.w"
  707. ;
  708. /*37:*/
  709. #line 683 "common.w"
  710.  
  711. p= hash[h];
  712. while(p&&!names_match(p,first,l,t))p= p->link;
  713. if(p==NULL){
  714. p= name_ptr;
  715. p->link= hash[h];hash[h]= p;
  716. }
  717.  
  718. /*:37*/
  719. #line 666 "common.w"
  720. ;
  721. if(p==name_ptr)/*39:*/
  722. #line 698 "common.w"
  723. {
  724. if(byte_ptr+l>byte_mem_end)overflow("byte memory");
  725. if(name_ptr>=name_dir_end)overflow("name");
  726. strncpy(byte_ptr,first,l);
  727. (++name_ptr)->byte_start= byte_ptr+= l;
  728. if(program==cweave)init_p(p,t);
  729. }
  730.  
  731. /*:39*/
  732. #line 667 "common.w"
  733. ;
  734. return(p);
  735. }
  736.  
  737. /*:35*//*42:*/
  738. #line 756 "common.w"
  739.  
  740. void
  741. print_section_name(p)
  742. name_pointer p;
  743. {
  744. char*ss,*s= first_chunk(p);
  745. name_pointer q= p+1;
  746. while(p!=name_dir){
  747. ss= (p+1)->byte_start-1;
  748. if(*ss==' '&&ss>=s){
  749. term_write(s,ss-s);p= q->link;q= p;
  750. }else{
  751. term_write(s,ss+1-s);p= name_dir;q= NULL;
  752. }
  753. s= p->byte_start;
  754. }
  755. if(q)term_write("...",3);
  756. }
  757.  
  758. /*:42*//*43:*/
  759. #line 775 "common.w"
  760.  
  761. void
  762. sprint_section_name(dest,p)
  763. char*dest;
  764. name_pointer p;
  765. {
  766. char*ss,*s= first_chunk(p);
  767. name_pointer q= p+1;
  768. while(p!=name_dir){
  769. ss= (p+1)->byte_start-1;
  770. if(*ss==' '&&ss>=s){
  771. p= q->link;q= p;
  772. }else{
  773. ss++;p= name_dir;
  774. }
  775. strncpy(dest,s,ss-s),dest+= ss-s;
  776. s= p->byte_start;
  777. }
  778. *dest= '\0';
  779. }
  780.  
  781. /*:43*//*44:*/
  782. #line 796 "common.w"
  783.  
  784. void
  785. print_prefix_name(p)
  786. name_pointer p;
  787. {
  788. char*s= first_chunk(p);
  789. int l= prefix_length(p);
  790. term_write(s,l);
  791. if(s+l<(p+1)->byte_start)term_write("...",3);
  792. }
  793.  
  794. /*:44*//*45:*/
  795. #line 817 "common.w"
  796.  
  797. int web_strcmp(j,j_len,k,k_len)
  798. char*j,*k;
  799. int j_len,k_len;
  800. {
  801. char*j1= j+j_len,*k1= k+k_len;
  802. while(k<k1&&j<j1&&*j==*k)k++,j++;
  803. if(k==k1)if(j==j1)return equal;
  804. else return extension;
  805. else if(j==j1)return prefix;
  806. else if(*j<*k)return less;
  807. else return greater;
  808. }
  809.  
  810. /*:45*//*47:*/
  811. #line 847 "common.w"
  812.  
  813. name_pointer
  814. add_section_name(par,c,first,last,ispref)
  815. name_pointer par;
  816. int c;
  817. char*first;
  818. char*last;
  819. int ispref;
  820. {
  821. name_pointer p= name_ptr;
  822. char*s= first_chunk(p);
  823. int name_len= last-first+ispref;
  824. if(s+name_len>byte_mem_end)overflow("byte memory");
  825. if(name_ptr+1>=name_dir_end)overflow("name");
  826. (++name_ptr)->byte_start= byte_ptr= s+name_len;
  827. if(ispref){
  828. *(byte_ptr-1)= ' ';
  829. name_len--;
  830. name_ptr->link= name_dir;
  831. (++name_ptr)->byte_start= byte_ptr;
  832. }
  833. set_prefix_length(p,name_len);
  834. strncpy(s,first,name_len);
  835. p->llink= NULL;
  836. p->rlink= NULL;
  837. init_node(p);
  838. return par==NULL?(root= p):c==less?(par->llink= p):(par->rlink= p);
  839. }
  840.  
  841. /*:47*//*48:*/
  842. #line 876 "common.w"
  843.  
  844. void
  845. extend_section_name(p,first,last,ispref)
  846. name_pointer p;
  847. char*first;
  848. char*last;
  849. int ispref;
  850. {
  851. char*s;
  852. name_pointer q= p+1;
  853. int name_len= last-first+ispref;
  854. if(name_ptr>=name_dir_end)overflow("name");
  855. while(q->link!=name_dir)q= q->link;
  856. q->link= name_ptr;
  857. s= name_ptr->byte_start;
  858. name_ptr->link= name_dir;
  859. if(s+name_len>byte_mem_end)overflow("byte memory");
  860. (++name_ptr)->byte_start= byte_ptr= s+name_len;
  861. strncpy(s,first,name_len);
  862. if(ispref)*(byte_ptr-1)= ' ';
  863. }
  864.  
  865. /*:48*//*49:*/
  866. #line 904 "common.w"
  867.  
  868. name_pointer
  869. section_lookup(first,last,ispref)
  870. char*first,*last;
  871. int ispref;
  872. {
  873. int c= 0;
  874. name_pointer p= root;
  875. name_pointer q= NULL;
  876. name_pointer r= NULL;
  877. name_pointer par= NULL;
  878.  
  879. int name_len= last-first+1;
  880. /*50:*/
  881. #line 928 "common.w"
  882.  
  883. while(p){
  884. c= web_strcmp(first,name_len,first_chunk(p),prefix_length(p));
  885. if(c==less||c==greater){
  886. if(r==NULL)
  887. par= p;
  888. p= (c==less?p->llink:p->rlink);
  889. }else{
  890. if(r!=NULL){
  891. printf("\n! Ambiguous prefix: matches <");
  892.  
  893. print_prefix_name(p);
  894. printf(">\n and <");
  895. print_prefix_name(r);
  896. err_print(">");
  897. return name_dir;
  898. }
  899. r= p;
  900. p= p->llink;
  901. q= r->rlink;
  902. }
  903. if(p==NULL)
  904. p= q,q= NULL;
  905. }
  906.  
  907. /*:50*/
  908. #line 918 "common.w"
  909. ;
  910. /*51:*/
  911. #line 953 "common.w"
  912.  
  913. if(r==NULL)
  914. return add_section_name(par,c,first,last+1,ispref);
  915.  
  916. /*:51*/
  917. #line 919 "common.w"
  918. ;
  919. /*52:*/
  920. #line 961 "common.w"
  921.  
  922. switch(section_name_cmp(&first,name_len,r)){
  923.  
  924. case prefix:
  925. if(!ispref){
  926. printf("\n! New name is a prefix of <");
  927.  
  928. print_section_name(r);
  929. err_print(">");
  930. }
  931. else if(name_len<prefix_length(r))set_prefix_length(r,name_len);
  932.  
  933. case equal:return r;
  934. case extension:if(!ispref||first<=last)
  935. extend_section_name(r,first,last+1,ispref);
  936. return r;
  937. case bad_extension:
  938. printf("\n! New name extends <");
  939.  
  940. print_section_name(r);
  941. err_print(">");
  942. return r;
  943. default:
  944. printf("\n! Section name incompatible with <");
  945.  
  946. print_prefix_name(r);
  947. printf(">,\n which abbreviates <");
  948. print_section_name(r);
  949. err_print(">");
  950. return r;
  951. }
  952.  
  953. /*:52*/
  954. #line 920 "common.w"
  955. ;
  956. }
  957.  
  958. /*:49*//*54:*/
  959. #line 1012 "common.w"
  960.  
  961. int section_name_cmp(pfirst,len,r)
  962. char**pfirst;
  963. int len;
  964. name_pointer r;
  965. {
  966. char*first= *pfirst;
  967. name_pointer q= r+1;
  968. char*ss,*s= first_chunk(r);
  969. int c;
  970. int ispref;
  971. while(1){
  972. ss= (r+1)->byte_start-1;
  973. if(*ss==' '&&ss>=r->byte_start)ispref= 1,q= q->link;
  974. else ispref= 0,ss++,q= name_dir;
  975. switch(c= web_strcmp(first,len,s,ss-s)){
  976. case equal:if(q==name_dir)
  977. if(ispref){
  978. *pfirst= first+(ss-s);
  979. return extension;
  980. }else return equal;
  981. else return(q->byte_start==(q+1)->byte_start)?equal:prefix;
  982. case extension:
  983. if(!ispref)return bad_extension;
  984. first+= ss-s;
  985. if(q!=name_dir){len-= ss-s;s= q->byte_start;r= q;continue;}
  986. *pfirst= first;return extension;
  987. default:return c;
  988. }
  989. }
  990. }
  991.  
  992. /*:54*//*58:*/
  993. #line 1087 "common.w"
  994.  
  995. void
  996. err_print(s)
  997. char*s;
  998. {
  999. char*k,*l;
  1000. printf(*s=='!'?"\n%s":"%s",s);
  1001. if(web_file_open)/*59:*/
  1002. #line 1107 "common.w"
  1003.  
  1004. {if(changing&&include_depth==change_depth)
  1005. printf(". (l. %d of change file)\n",change_line);
  1006. else if(include_depth==0)printf(". (l. %d)\n",cur_line);
  1007. else printf(". (l. %d of include file %s)\n",cur_line,cur_file_name);
  1008. l= (loc>=limit?limit:loc);
  1009. if(l>buffer){
  1010. for(k= buffer;k<l;k++)
  1011. if(*k=='\t')putchar(' ');
  1012. else putchar(*k);
  1013. putchar('\n');
  1014. for(k= buffer;k<l;k++)putchar(' ');
  1015. }
  1016. for(k= l;k<limit;k++)putchar(*k);
  1017. if(*limit=='|')putchar('|');
  1018. putchar(' ');
  1019. }
  1020.  
  1021. /*:59*/
  1022. #line 1094 "common.w"
  1023. ;
  1024. update_terminal;mark_error;
  1025. }
  1026.  
  1027. /*:58*//*61:*/
  1028. #line 1142 "common.w"
  1029.  
  1030. int wrap_up(){
  1031. putchar('\n');
  1032. if(show_stats)
  1033. print_stats();
  1034. /*62:*/
  1035. #line 1152 "common.w"
  1036.  
  1037. switch(history){
  1038. case spotless:if(show_happiness)printf("(No errors were found.)\n");break;
  1039. case harmless_message:
  1040. printf("(Did you see the warning message above?)\n");break;
  1041. case error_message:
  1042. printf("(Pardon me, but I think I spotted something wrong.)\n");break;
  1043. case fatal_message:printf("(That was a fatal error, my friend.)\n");
  1044. }
  1045.  
  1046. /*:62*/
  1047. #line 1147 "common.w"
  1048. ;
  1049. if(history>harmless_message)return(1);
  1050. else return(0);
  1051. }
  1052.  
  1053. /*:61*//*64:*/
  1054. #line 1171 "common.w"
  1055. void
  1056. fatal(s,t)
  1057. char*s,*t;
  1058. {
  1059. if(*s)printf(s);
  1060. err_print(t);
  1061. history= fatal_message;exit(wrap_up());
  1062. }
  1063.  
  1064. /*:64*//*65:*/
  1065. #line 1182 "common.w"
  1066. void
  1067. overflow(t)
  1068. char*t;
  1069. {
  1070. printf("\n! Sorry, %s capacity exceeded",t);fatal("","");
  1071. }
  1072.  
  1073.  
  1074. /*:65*//*70:*/
  1075. #line 1246 "common.w"
  1076.  
  1077. void
  1078. scan_args()
  1079. {
  1080. char*dot_pos;
  1081. char*name_pos;
  1082. register char*s;
  1083. boolean found_web= 0,found_change= 0,found_out= 0;
  1084.  
  1085. boolean flag_change;
  1086.  
  1087. while(--argc>0){
  1088. if((**(++argv)=='-'||**argv=='+')&&*(*argv+1))/*74:*/
  1089. #line 1340 "common.w"
  1090.  
  1091. {
  1092. if(**argv=='-')flag_change= 0;
  1093. else flag_change= 1;
  1094. for(dot_pos= *argv+1;*dot_pos>'\0';dot_pos++)
  1095. flags[*dot_pos]= flag_change;
  1096. }
  1097.  
  1098. /*:74*/
  1099. #line 1258 "common.w"
  1100.  
  1101. else{
  1102. s= name_pos= *argv;dot_pos= NULL;
  1103. while(*s){
  1104. if(*s=='.')dot_pos= s++;
  1105. else if(*s=='/')dot_pos= NULL,name_pos= ++s;
  1106. else s++;
  1107. }
  1108. if(!found_web)/*71:*/
  1109. #line 1284 "common.w"
  1110.  
  1111. {
  1112. if(s-*argv>max_file_name_length-5)
  1113. /*76:*/
  1114. #line 1360 "common.w"
  1115. fatal("! Filename too long\n",*argv);
  1116.  
  1117.  
  1118. /*:76*/
  1119. #line 1287 "common.w"
  1120. ;
  1121. if(dot_pos==NULL)
  1122. sprintf(web_file_name,"%s.w",*argv);
  1123. else{
  1124. strcpy(web_file_name,*argv);
  1125. *dot_pos= 0;
  1126. }
  1127. sprintf(alt_web_file_name,"%s.web",*argv);
  1128. sprintf(tex_file_name,"%s.tex",name_pos);
  1129. sprintf(idx_file_name,"%s.idx",name_pos);
  1130. sprintf(scn_file_name,"%s.scn",name_pos);
  1131. sprintf(C_file_name,"%s.c",name_pos);
  1132. found_web= 1;
  1133. }
  1134.  
  1135. /*:71*/
  1136. #line 1267 "common.w"
  1137.  
  1138. else if(!found_change)/*72:*/
  1139. #line 1302 "common.w"
  1140.  
  1141. {
  1142. if(strcmp(*argv,"-")==0)found_change= -1;
  1143. else{
  1144. if(s-*argv>max_file_name_length-4)
  1145. /*76:*/
  1146. #line 1360 "common.w"
  1147. fatal("! Filename too long\n",*argv);
  1148.  
  1149.  
  1150. /*:76*/
  1151. #line 1307 "common.w"
  1152. ;
  1153. if(dot_pos==NULL)
  1154. sprintf(change_file_name,"%s.ch",*argv);
  1155. else strcpy(change_file_name,*argv);
  1156. found_change= 1;
  1157. }
  1158. }
  1159.  
  1160. /*:72*/
  1161. #line 1268 "common.w"
  1162.  
  1163. else if(!found_out)/*73:*/
  1164. #line 1315 "common.w"
  1165.  
  1166. {
  1167. if(s-*argv>max_file_name_length-5)
  1168. /*76:*/
  1169. #line 1360 "common.w"
  1170. fatal("! Filename too long\n",*argv);
  1171.  
  1172.  
  1173. /*:76*/
  1174. #line 1318 "common.w"
  1175. ;
  1176. if(dot_pos==NULL){
  1177. sprintf(tex_file_name,"%s.tex",*argv);
  1178. sprintf(idx_file_name,"%s.idx",*argv);
  1179. sprintf(scn_file_name,"%s.scn",*argv);
  1180. sprintf(C_file_name,"%s.c",*argv);
  1181. }else{
  1182. strcpy(tex_file_name,*argv);
  1183. if(flags['x']){
  1184. if(program==cweave&&strcmp(*argv+strlen(*argv)-4,".tex")!=0)
  1185. fatal("! Output file name should end with .tex\n",*argv);
  1186.  
  1187. strcpy(idx_file_name,*argv);
  1188. strcpy(idx_file_name+strlen(*argv)-4,".idx");
  1189. strcpy(scn_file_name,*argv);
  1190. strcpy(scn_file_name+strlen(*argv)-4,".scn");
  1191. }
  1192. strcpy(C_file_name,*argv);
  1193. }
  1194. found_out= 1;
  1195. }
  1196.  
  1197. /*:73*/
  1198. #line 1269 "common.w"
  1199.  
  1200. else/*75:*/
  1201. #line 1348 "common.w"
  1202.  
  1203. {
  1204. if(program==ctangle)
  1205. fatal(
  1206. "! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
  1207. ,"");
  1208.  
  1209. else fatal(
  1210. "! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
  1211. ,"");
  1212. }
  1213.  
  1214. /*:75*/
  1215. #line 1270 "common.w"
  1216. ;
  1217. }
  1218. }
  1219. if(!found_web)/*75:*/
  1220. #line 1348 "common.w"
  1221.  
  1222. {
  1223. if(program==ctangle)
  1224. fatal(
  1225. "! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
  1226. ,"");
  1227.  
  1228. else fatal(
  1229. "! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
  1230. ,"");
  1231. }
  1232.  
  1233. /*:75*/
  1234. #line 1273 "common.w"
  1235. ;
  1236. if(found_change<=0)strcpy(change_file_name,"/dev/null");
  1237. }
  1238.  
  1239. /*:70*/
  1240.